<template>
  <view class="Bluetooth">
    <view v-if="tip.stop === false" class="start">
      <!-- 波纹圈 -->
      <view class="ripple">
        <view class="avatar">
          <image class="image" src="../../static/image/Bluetooth/Bluetooth-wirte.png"></image>
        </view>
        <view class="inner"></view>
        <view class="inner outter"></view>
      </view>
      <view class="center">
        <view class="title">{{ tip.title }}</view>
        <view class="describe">{{ tip.describe }}</view>
      </view>
    </view>
    <view v-else class="end">
      <view class="e-icon">
        <u-icon name="clock" size="100"></u-icon>
      </view>
      <view class="center">
        <view class="title">{{ tip.endTitle }}</view>
        <view class="title">{{ tip.endTitle2 }}</view>
        <view class="title">{{ tip.endTitle3 }}</view>
        <u-button size="medium" type="primary" @click="openBluetoothAdapter">{{ tip.btnText }}</u-button>
      </view>
    </view>

    <authComponent ref="authComponent" :subTitle="auth.subTitle" :title="auth.title" @close="close"
                   @submit="submit"></authComponent>
  </view>
</template>
<script>
let timer
import {mapGetters, mapMutations} from "vuex"

export default {
  components: {},
  computed: {
    ...mapGetters(['Bluetooth', 'api', 'userInfo'])
  },
  data() {
    return {
      aginNum: 0,//重连次数
      tip: {
        title: this.$t('正在初始化设备'),
        describe: this.$t('初始化完成后，将重新进行蓝牙连接'),
        stop: false,//当前是否扫描蓝牙失败，是否进行再次扫描
        endTitle: this.$t('蓝牙连接超时'),
        endTitle2: this.$t('请确保设备处于开机状态'),
        endTitle3: this.$t('将手机靠近设备'),
        btnText: this.$t('再次扫描')
      },
      parms: {//扫码传参过来的值
        url: '',
        sn: '',
        endSn: '',//截取sn的后四位然后和16进制的特征值做对比，如果里面包含了此值就进行连接
        from: '',//来自哪里
        afterTo: '',//处理完之后需要做什么
        data: '',//跳转需要的参数
        deviceId: ''
      },
      activeBle: {//当前已经连接上的蓝牙
        deviceId: '',
        serviceId: '',
        write: {
          characteristicId: '',
        },
        read: {//监听蓝牙信息
          characteristicId: '',
        }
      },
      auth: {
        title: '',
        subTitle: this.$t('请输入认证密码，以验证身份')
      },
      blueAuth: {}
    };
  },
  onBackPress(options) {
    uni.closeBluetoothAdapter();
    this.$lizhao.bluetooth.stopBluetoothDevicesDiscovery()
    clearTimeout(timer)
  },
  onLoad(data) {
    if (data.data) {
      //获取到扫码传过来的值
      this.parms.url = decodeURIComponent(data.data)
      //console.log('url', this.parms.url)
      //获取url中的sn值//去除两端空格
      this.parms.sn = this.$u.trim(this.$lizhao.url.getQueryString(this.parms.url, 'sn'))
      //获取sn值中的后4位数,然后和16进制的特征值做对比，如果里面包含了此值就进行连接
      this.parms.endSn = this.parms.sn.slice(this.parms.sn.length - 4, this.parms.sn.length)
      //来自哪里
      this.parms.from = data.from
      //设备id
      this.parms.deviceId = data.deviceId
      //组织id
      this.parms.orgId = data.orgId
      //处理完之后需要做什么
      this.parms.afterTo = data.afterTo || ''
      if (data.from === '蓝牙推送') {
        this.parms.data = data.parms
      }
    }
    this.set_BlueToothDeviceInfo(this.parms)
    //监听回复
    uni.$off('onBLECharacteristicValueChange')
    uni.$on('onBLECharacteristicValueChange', (res) => {
      //console.log(res);
      if (res.cmd === 7) {//设备绑定
      } else if (res.cmd === 8) {//设备随机数
        let timestamp = new Date().getTime()
        let deviceId = this.parms.deviceId || ''
        let orgId = this.parms.orgId || ''
        let payload = this.$lizhao.sha256(orgId + deviceId + res.data.random + this.Bluetooth.P20_BLE_AUTH_KEY + timestamp)
        this.blueAuth = {
          corpId: orgId,
          deviceId: deviceId,
          payload,
          timestamp
        }
        //发送auth验证
        this.bluetoothAuth()
      } else if (res.cmd === 9) {
        if (res.data && res.data.code === 200) {//鉴权成功
          //手机安全认证
          this.safetyCertification()
        } else if (res.data && res.data.code === 400) {
          uni.showToast({
            title: this.$t('未生成随机数'),
            icon: "none"
          });
        } else if (res.data && res.data.code === 401) {
          uni.showToast({
            title: this.$t('随机数已过期'),
            icon: "none"
          });
        } else if (res.data && res.data.code === 402) {
          uni.showToast({
            title: this.$t('校验失败'),
            icon: "none"
          });
        }
      } else if (res.cmd === 3) {//设备信息获取成功
        //判断需要做什么
        this.needsToFn()
      }
    })

  },
  onShow() {
    uni.setNavigationBarTitle({title: this.$t('蓝牙')})

    //#ifdef MP-WEIXIN
    uni.closeBluetoothAdapter();
    //#endif
    //初始化蓝牙 获取本机蓝牙适配器状态
    if (this.parms.from === '扫码') {
      uni.navigateTo({
        url: '../bluetooth/IntelligentSeal/IntelligentSeal?id=' + this.parms.sn + '&from=' + this.parms.from
      })
    } else {
      this.aginNum = 0
      setTimeout(() => {
        this.hasCertKey()
      }, 500)
    }
  },
  methods: {
    ...mapMutations(['set_BlueToothActiveBle', 'set_BlueToothDeviceInfo']),
    openBluetoothAdapter() {
      uni.closeBluetoothAdapter();
      this.tip = {
        title: this.$t('正在初始化设备'),
        describe: this.$t('初始化完成后，将重新进行蓝牙连接'),
        stop: false,//当前是否扫描蓝牙失败，是否进行再次扫描
        endTitle: this.$t('蓝牙连接超时'),
        endTitle2: this.$t('请确保设备处于开机状态'),
        endTitle3: this.$t('将手机靠近设备'),
        btnText: this.$t('再次扫描')
      }
      this.aginNum = 0
      clearTimeout(timer)
      this.hasCertKey()
    },
    hasCertKey() {
      //检测是否设置过认证密码
      if (!this.userInfo.hasCertKey) {
        uni.showModal({
          title: this.$t('提示'),
          content: this.$t('检测到您未设置安全认证密码，请先设置后再操作'),
          cancelText: this.$t('取消'),
          confirmText: this.$t('确定'),
          success: res => {
            if (res.confirm) {
              uni.navigateTo({
                url: `/pages/template/safetyCertification/setPassword/setPassword?title=${this.$t('设置认证密码')}&subTitle=${this.$t('请输入认证密码以验证身份')}`
              });
            }
            if (res.cancel) {
              this.close()
            }
          },
          fail: () => {
          },
          complete: () => {
          }
        });
        return
      } else {
        this.init()
      }
    },
    //初始化蓝牙 获取本机蓝牙适配器状态
    init() {
      this.$lizhao.bluetooth.init((status) => {
        //获取本机蓝牙适配器状态成功
        this.tip.title = this.$t('正在搜索蓝牙设备') + '...'
        clearTimeout(timer)
        timer = setTimeout(() => {
          this.aginNum++
          if (this.aginNum === 1 && this.tip.stop === false) {//第二次尝试在连接一次
            this.init()
          } else {//第二次连接失败后显示连接超时
            this.tip.stop = true
            this.$lizhao.bluetooth.stopBluetoothDevicesDiscovery()
          }
        }, 7000)
        //开始搜索蓝牙，发现外围设备
        this.$lizhao.bluetooth.startBluetoothDevicesDiscovery(async devices => {
          //ArrayBuffer转16进度字符串示例
          let ManufacturerData = this.$lizhao.scale.ab2hex(devices.devices[0].advertisData)
          // //console.log('ManufacturerData',ManufacturerData)
          //截取特征值的第26位到34位的hex值
          let endSn = ManufacturerData.slice(26, 34)
          // //console.log(endSn);
          if (endSn) {
            //获取到的16进制转换成字符串
            let str = await this.$lizhao.scale.hexCharCodeToStr(endSn);
            //如果当前特征值和扫码url中sn的后四位相等 就进行连接蓝牙
            if (str === this.parms.endSn) {
              //console.log('16进制转换成字符串',str,this.parms.endSn);
              //console.log('devices.devices[0]',devices.devices[0]);
              //已经获取到指定的蓝牙设备，全局设置
              this.set_BlueToothActiveBle(devices.devices[0])
              //4.停止搜索蓝牙
              this.$lizhao.bluetooth.stopBluetoothDevicesDiscovery()
              this.tip.title = this.$t('已获取到蓝牙，正在安全认证') + '...'
              //建立连接
              this.$lizhao.bluetooth.createBLEConnection(activeBle => {
                //已连接。并获取到可写可监听的特征值成功
                //console.log('当前蓝牙可写可监听服务',activeBle);
                this.$lizhao.bluetooth.onBLEConnectionStateChange()
                // 启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值。
                this.$lizhao.bluetooth.notifyBLECharacteristicValueChange()
                //开启蓝牙监听
                this.$lizhao.bluetooth.readBLECharacteristicValue()
                //4.停止搜索蓝牙
                this.$lizhao.bluetooth.stopBluetoothDevicesDiscovery()
                clearTimeout(timer)
                //蓝牙鉴权（先获取random）
                this.getrandom()

              }, (err) => {
                //console.log(err);
                if (err === -1) {
                  uni.closeBluetoothAdapter();
                  this.init()
                } else {
                  this.aginNum++
                  if (this.aginNum < 3) {
                    this.init()
                  }
                }
              })
            }

          }
        })
      }, err => {
        //console.log('初始化出错',err);
      })
    },
    //获取random
    getrandom() {
      //获取随机数Random
      let body = {}
      let cmd = '0008'//8转成两位的16进制为00 08
      let len = '00000002'//body的长度为2转成4位的16进制为00 00 00 02
      //获取输入框的十进制数据转换为16进制
      let body_16 = this.$lizhao.scale.strToHexCharCode(JSON.stringify(body))
      let hex = this.Bluetooth.agreement.magic + cmd + this.Bluetooth.agreement.id + len + body_16
      //写入指令
      this.$lizhao.bluetooth.writeBLECharacteristicValue(hex)
    },
    //蓝牙鉴权
    bluetoothAuth() {
      let body = this.blueAuth
      let length = this.$lizhao.scale.switch_sl(JSON.stringify(body).length, 16)// 十进制转十六进制
      let stri = '0'
      for (let i = 0; i < (7 - length.length); i++) {
        stri += '0'
      }
      //计算出body长度
      let len = stri + length//body的长度为39转成4位的16进制为00 00 00 26
      let cmd = '0009'//9转成两位的16进制为00 09
      //body转成16进制 十进制数据转换为16进制
      let body_16 = this.$lizhao.scale.strToHexCharCode(JSON.stringify(body))
      let hex = this.Bluetooth.agreement.magic + cmd + this.Bluetooth.agreement.id + len + body_16
      let arr = this.splitArr(hex)
      //多个指令串行发送，并行可能会失败
      this.writeCmd(arr, 0, '蓝牙鉴权')
    },
    //arr为hex分割的数组，i为当前数组下标
    async writeCmd(arr, i, text) {
      let res = await this.$lizhao.bluetooth.writeBLECharacteristicValue(arr[i])
      if (res === 'writeBLECharacteristicValue:ok') {
        i++
        if (i > arr.length) {
          return
        }
        this.$lizhao.sleep.sleep(50)
        this.writeCmd(arr, i, text)
      } else {
        this.aginNum++
        if (this.aginNum > 5) {
          this.aginNum = 0
          return
        }
        if (text === '蓝牙鉴权') {
          this.bluetoothAuth()
        }
      }

    },
    //分割指令每20位分割一下，返回数组
    splitArr(hex) {
      let arr = []
      for (let a = 0; a < Math.ceil(hex.length / 20); a++) {
        let str = hex.slice(a * 20, a * 20 + 20)
        arr.push(str)
      }
      return arr
    },
    //安全认证
    safetyCertification() {
      //只有在临时盖章、更换印章、申请单盖章才需要安全认证
      if (this.parms.from === '临时盖章' || this.parms.from === '更换印章' || this.parms.from === '蓝牙推送') {
        this.$refs.authComponent.showPop(true)
      } else {
        this.navigetPage()
      }

    },
    close(value) {
      this.$refs.authComponent.showPop(false)
      this.tip.stop = true
      this.tip.endTitle = this.$t('认证失败或已取消')
      this.tip.endTitle2 = ''
      this.tip.endTitle3 = ''
      this.tip.btnText = this.$t('重试')
      uni.closeBluetoothAdapter();
    },
    submit(value) {
      //console.log(value);
      if (value === '指纹验证成功') {
        this.navigetPage()
      } else if (value === '无密码认证') {
        this.navigetPage()
      } else {
        this.validate(value)
      }
    },
    validate(value) {
      this.$u.post(this.api.GLOBAL_sysUserCert_validate, {certSecretKey: value}).then(res => {
        if (res.code === 200) {
          this.$refs.authComponent.showPop(false)
          uni.showToast({
            title: this.$t('验证成功')
          });
          this.navigetPage()
        }
      });
    },
    navigetPage() {
      //获取设备信息
      this.GetDeviceInfo()
      //判断需要做什么
      // this.needsToFn()
    },
    //获取设备信息
    GetDeviceInfo() {
      let body = {}
      let cmd = '0003'//3转成两位的16进制为00 03
      let len = '00000002'//body的长度为2转成4位的16进制为00 00 00 02
      //获取输入框的十进制数据转换为16进制
      let body_16 = this.$lizhao.scale.strToHexCharCode(JSON.stringify(body))
      let hex = this.Bluetooth.agreement.magic + cmd + this.Bluetooth.agreement.id + len + body_16
      //写入指令
      this.$lizhao.bluetooth.writeBLECharacteristicValue(hex)
    },
    //判断需要做什么
    needsToFn() {
      if (this.parms.from === '临时盖章') {
        uni.redirectTo({url: '../bluetooth/temporarySeal/temporarySeal'});
      } else if (this.parms.from === '蓝牙推送') {
        uni.redirectTo({
          url: '../bluetooth/ToSeal/ToSeal?data=' + this.parms.data
        })
      } else if (this.parms.from === '设置wifi') {
        uni.redirectTo({
          url: '../bluetooth/bluetoothWifi/bluetoothWifi'
        })
      } else if (this.parms.from === '绑定组织') {
        uni.redirectTo({
          url: `../bluetooth/deviceBind/deviceBind`
        })
      } else if (this.parms.from === '更换印章') {
        uni.redirectTo({
          url: `../bluetooth/changeSeal/changeSeal`
        })
      } else if (this.parms.from === '设备信息') {
        uni.redirectTo({
          url: `../bluetooth/deviceInfo/deviceInfo?id=` + this.parms.deviceId
        })
      }
    },
    //点击选取组织确认
    onConfirm(e) {
      //console.log(e.value[0]);
    },
    //设备绑定
    deviceBind() {
      //console.log(this.parms.sn);
      uni.navigateTo({
        // url:`./deviceBind/deviceBind?sn=${this.parms.sn}`
        url: `../bluetooth/deviceBind/deviceBind?sn=123456789`
      })
    },
    //获取wifi列表
    setWifiConfig() {
      let body = {}
      let cmd = '0001'//1转成两位的16进制为00 01
      let len = '00000002'//body的长度为2转成4位的16进制为00 00 00 02
      //获取输入框的十进制数据转换为16进制
      let body_16 = this.$lizhao.scale.strToHexCharCode(JSON.stringify(body))
      let hex = this.Bluetooth.agreement.magic + cmd + this.Bluetooth.agreement.id + len + body_16
      //console.log('最终的16进制的指令',hex);
      //写入指令
      this.$lizhao.bluetooth.writeBLECharacteristicValue(hex)

    },

  }
};
</script>

<style lang="scss" scoped>
.Bluetooth {
  width: 100%;
  // 波纹圈
  .ripple {
    position: relative;
    width: 100%;
    height: 500rpx;

    .inner {
      width: 200rpx;
      height: 200rpx;
      background: #00aaff;
      border-radius: 50%;
      position: absolute;
      left: 0;
      right: 0;
      margin: auto;
      margin-top: 200rpx;
      z-index: 10;
      animation-duration: 1.5s;
      -webkit-animation-name: state1;
      animation-name: state1;
      -webkit-animation-timing-function: linear;
      animation-timing-function: linear;
      -webkit-animation-iteration-count: infinite;
      animation-iteration-count: infinite;
      opacity: 0;
    }

    @keyframes state1 {
      0% {
        opacity: .5;
        -webkit-transform: scale(1);
        transform: scale(1);
      }

      100% {
        opacity: 0;
        -webkit-transform: scale(2.5);
        transform: scale(2.5);
      }
    }

    .avatar {
      position: absolute;
      left: 0;
      right: 0;
      margin: auto;
      border-radius: 100%;
      margin-top: 200rpx;
      width: 200rpx;
      height: 200rpx;
      background-color: #00aaff;
      z-index: 11;
      display: flex;
      justify-content: center;
      align-items: center;

      .image {
        width: 100rpx;
        height: 100rpx;
        margin: auto;
      }
    }

    .outter {
      animation-delay: 0.3s;
    }
  }

  .center {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;

    .title {
      text-align: center;
      font-size: 36rpx;
      font-weight: bold;
      margin-bottom: 20rpx;
    }

    .describe {
      color: #888;
      font-size: 26rpx;
    }
  }

  .end {
    margin-top: 100rpx;
    display: flex;
    flex-direction: column;
    align-items: center;

    .e-icon {
      width: 200rpx;
      height: 200rpx;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #ffaa00;
      color: #fff;
      margin: 100rpx 0 50rpx 0;
    }
  }
}
</style>
